package com.system.common.filter;

import com.system.common.constant.SessionKeyConst;
import com.system.common.entity.person.Person;
import com.system.common.service.persion.PersonService;
import com.system.common.service.purview.PurviewService;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Objects;
import java.util.Set;

import static com.system.common.controller.IndexController.LOGIN_UI;

/**
 * url拦截规则
 * 1. 静态资源不拦截
 * 2. 查询是否要登陆
 * 2.1 要登陆则判断是否已经登陆
 * 3.1 已登陆则查看用户是否有权限访问
 */
@Component
public class WebUrlFilter implements Filter {

    private static final Logger logger = LoggerFactory.getLogger(WebUrlFilter.class);
    private static final String NO_FILTER = "/static/";

    @Autowired
    private PurviewService purviewService;

    @Autowired
    private PersonService personService;

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;

        String url = request.getServletPath();
        if (url.startsWith(NO_FILTER)) {
            // 静态资源直接过
            filterChain.doFilter(request, response);
        } else {
            // 查询所有不用登陆的权限
            if (purviewService.noNeedLogin(url)) {
                filterChain.doFilter(request, response);
                return;
            }
            String token = null;
            Cookie[] cookies = request.getCookies();
            if (cookies == null || cookies.length == 0) {
                // 未登陆或token无效则跳转到登陆页面
                logger.info("未登陆或token无效则跳转到登陆页面,url:{}", url);
                response.sendRedirect(request.getContextPath() + LOGIN_UI);
                return;
            }
            for (Cookie cookie : cookies) {
                if (Objects.equals(SessionKeyConst.LOGIN_TOKEN, cookie.getName())) {
                    token = cookie.getValue();
                    break;
                }
            }

            if (StringUtils.isBlank(token)) {
                // 未登陆或token无效则跳转到登陆页面
                logger.info("未登陆或token无效则跳转到登陆页面,url:{}", url);
                response.sendRedirect(request.getContextPath() + LOGIN_UI);
                return;
            }
            HttpSession session = request.getSession();

            Long personId = (Long) session.getAttribute(token);
            if (personId == null || personId == 0) {
                // 未登陆则跳转到登陆页面
                logger.info("未登陆或token无效则跳转到登陆页面,url:{}", url);
                response.sendRedirect(request.getContextPath() + LOGIN_UI);
                return;
            }
            Person person = personService.getPersonByToken(token, personId);
            if (person == null) {
                // 未登陆或token无效则跳转到登陆页面
                logger.info("未登陆或token无效则跳转到登陆页面,url:{}, personId:{}", url, personId);
                response.sendRedirect(request.getContextPath() + LOGIN_UI);
                return;
            }

            Object purviewObj = session.getAttribute(SessionKeyConst.PERSON_PURES);
            if (purviewObj == null) {
                // 未登陆则跳转到登陆页面
                logger.info("未登陆或token无效则跳转到登陆页面,url:{}, loginName:{}", url, person.getLoginName());
                response.sendRedirect(request.getContextPath() + LOGIN_UI);
                return;
            }
            Set<String> purview = (Set<String>) purviewObj;
            if (CollectionUtils.isEmpty(purview)) {
                logger.info("用户[{},{}]没有权限访问该地址:[{}]", personId, person.getLoginName(), url);
                // 未登陆则跳转到登陆页面
                response.sendRedirect(request.getContextPath() + LOGIN_UI);
                return;
            }

            if (!purview.contains(url)) {
                logger.info("用户[{},{}]没有权限访问该地址:[{}]", personId, person.getLoginName(), url);
                response.sendRedirect(request.getContextPath() + LOGIN_UI);
                return;
            }
            filterChain.doFilter(request, response);
        }
    }

    @Override
    public void destroy() {

    }
}
